package com.statistics.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.common.utils.poi.ExcelUtil;
import com.statistics.domain.vo.*;
import com.statistics.mapper.EducationMapper;
import com.statistics.service.EducationService;
import com.statistics.util.EducationExportUtils;
import com.statistics.util.ScienceExchangeExportUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 教育部年度统计ServiceImpl
 *
 * @author chenyy
 * &#064;date 2025/3/10 11:41
 */
@Service
public class EducationServiceImpl implements EducationService {

    @Resource
    private EducationMapper educationMapper;

    @Override
    public void exportUnit(HttpServletResponse response, Integer type) {
        String[] fieldNames = Arrays.stream(ExportUnitVo.class.getDeclaredFields()).map(Field::getName).toArray(String[]::new);
        List<ExportUnitVo> vos = educationMapper.exportUnit(type);
        ExcelUtil<ExportUnitVo> excelUtil = new ExcelUtil<>(ExportUnitVo.class);
        excelUtil.showColumn(fieldNames);
        excelUtil.exportExcel(response, vos, "院系所数据导出");
    }

    @Override
    public void exportPerson(HttpServletResponse response) {
        String[] fieldNames = Arrays.stream(ExportPersonVo.class.getDeclaredFields()).map(Field::getName).toArray(String[]::new);
        List<ExportPersonVo> vos = educationMapper.exportPerson();
        ExcelUtil<ExportPersonVo> excelUtil = new ExcelUtil<>(ExportPersonVo.class);
        excelUtil.showColumn(fieldNames);
        excelUtil.exportExcel(response, vos, "社科活动人员数据导出");
    }

    @Override
    public void exportResAchieve(HttpServletResponse response, String year, Integer type) {
        String[] fieldNames = Arrays.stream(ExportResAchieveVo.class.getDeclaredFields()).map(Field::getName).toArray(String[]::new);
        List<ExportResAchieveVo> vos = educationMapper.exportResAchieve(year, type);
        ExcelUtil<ExportResAchieveVo> excelUtil = new ExcelUtil<>(ExportResAchieveVo.class);
        excelUtil.showColumn(fieldNames);
        excelUtil.exportExcel(response, vos, "科研成果数据导出");
    }

    @Override
    public void exportProject(HttpServletResponse response, String year, Integer type) {
        String[] fieldNames = Arrays.stream(ExportProjectVo.class.getDeclaredFields()).map(Field::getName).toArray(String[]::new);
        List<ExportProjectVo> vos = educationMapper.exportProject(year, type);
        ExcelUtil<ExportProjectVo> excelUtil = new ExcelUtil<>(ExportProjectVo.class);
        excelUtil.showColumn(fieldNames);
        excelUtil.exportExcel(response, vos, "科研项目数据导出");
    }

    @Override
    public void exportHonor(HttpServletResponse response, String year, Integer type) {
        String[] fieldNames = Arrays.stream(ExportHonorVo.class.getDeclaredFields()).map(Field::getName).toArray(String[]::new);
        List<ExportHonorVo> vos = educationMapper.exportHonor(year, type);
        ExcelUtil<ExportHonorVo> voExcelUtil = new ExcelUtil<>(ExportHonorVo.class);
        voExcelUtil.showColumn(fieldNames);
        voExcelUtil.exportExcel(response, vos, "成果获奖数据导出");
    }

    @Override
    public void exportResUnit(HttpServletResponse response, String year, Integer type) {
        String[] fieldNames = Arrays.stream(ExportResUnitVo.class.getDeclaredFields()).map(Field::getName).toArray(String[]::new);
        List<ExportResUnitVo> vos = educationMapper.exportResUnit(year, type);
        ExcelUtil<ExportResUnitVo> voExcelUtil = new ExcelUtil<>(ExportResUnitVo.class);
        voExcelUtil.showColumn(fieldNames);
        voExcelUtil.exportExcel(response, vos, "研究机构数据导出");
    }

    @Override
    public void exportResPerson(HttpServletResponse response) throws Exception {
        List<Map> maps = educationMapper.exportResPerson();
        EducationExportUtils.exportWithTemplate(response, maps, "科技人力资源情况表", 1);
    }

    @Override
    public void exportActivityUnit(HttpServletResponse response, String year, Integer type) throws Exception {
        List<Map> maps = educationMapper.exportActivityUnit(year, type);
        EducationExportUtils.exportWithTemplate(response, maps, "科技活动机构情况表", 2);
    }

    @Override
    public void exportScienceProject(HttpServletResponse response, String year, Integer type) throws Exception {
        List<Map> maps = educationMapper.exportScienceProject(year, type);
        EducationExportUtils.exportWithTemplate(response, maps, "科技项目情况表", 3);
    }

    @Override
    public void exportScienceInteract(HttpServletResponse response, String year) throws Exception {
        JSONObject json = new JSONObject();
        // 获取派遣和接收数据
        JSONObject dispatch = educationMapper.getPersonnel(year, "biz_personnel_dispatch");
        json.put("dispatch", dispatch);
        JSONObject accept = educationMapper.getPersonnel(year, "biz_personnel_accept");
        json.put("accept", accept);
        // 出席人员
        JSONObject personnel = educationMapper.getPersonnelReport(year, "biz_meeting", "person_number", "begin_date");
        json.put("personnel", personnel);
        // 交流论文
        JSONObject meetingPaper = educationMapper.getMeetingPaper(year);
        json.put("meetingPaper", meetingPaper);
        // 特邀报告
        JSONObject invitedPresentations = educationMapper.getPersonnelReport(year, "biz_join_meeting", "report_num", "meeting_date");
        json.put("invitedPresentations", invitedPresentations);
        // 主办会议
        JSONObject meeting = educationMapper.getMeeting(year);
        json.put("meeting", meeting);
        ScienceExchangeExportUtils.export(response, json, "科技交流情况表");
    }

    @Override
    public void exportScienceAchievement(HttpServletResponse response, String year, Integer type) throws Exception {
        List<Map> maps = educationMapper.exportScienceAchievement(year, type);
        EducationExportUtils.exportWithTemplate(response, maps, "科技成果情况表", 5);
    }

    @Override
    public void exportPublishBook(HttpServletResponse response, String year, Integer type) throws Exception {
        List<Map> maps = educationMapper.exportPublishBook(year, type);
        EducationExportUtils.exportWithTemplate(response, maps, "出版科技著作情况表", 6);
    }

    @Override
    public void exportScienceHonor(HttpServletResponse response, String year, Integer type) throws Exception {
        List<Map> maps = educationMapper.exportScienceHonor(year, type);
        EducationExportUtils.exportWithTemplate(response, maps, "科技成果奖励情况表", 7);

    }

    private void setFileDownloadHeader(HttpServletResponse response, String fileName) throws Exception {
        String encodedFileName = URLEncoder.encode(fileName, "UTF-8")
                .replaceAll("\\+", "%20");
        String headerValue = String.format("attachment; filename*=UTF-8''%s", encodedFileName);
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, headerValue);
    }

    @Override
    public void downloadTemplate(HttpServletResponse response, String subType) {
        String fileName = "";
        switch (subType) {
            case "项目年度工作量数据导出":
                fileName = "项目年度工作量导入模板.xlsx";
                break;
            case "项目年度经费数据导出":
                fileName = "项目年度经费导入模板.xlsx";
                break;
            case "科技经费数据导出":
                fileName = "科技经费情况表(模板).xlsx";
                break;
            case "技术转让与知识产权情况导出":
                fileName = "技术转让与知识产权情况表(模板).xlsx";
                break;
            case "科技期刊数据导出":
                fileName = "科技期刊情况表(模板).xlsx";
                break;
        }

        String filePath = "/templates/" + fileName;
        ClassPathResource resource = new ClassPathResource(filePath);

        if (!resource.exists()) {
            response.setStatus(HttpStatus.NOT_FOUND.value());
            return;
        }

        try (InputStream is = resource.getInputStream();
             OutputStream os = response.getOutputStream()) {

            // 设置响应头
            response.setContentType("application/octet-stream");
            setFileDownloadHeader(response, fileName);

            // 传输文件流
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = is.read(buffer)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.flush();

        } catch (Exception e) {
            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
            e.printStackTrace();
        }
    }

}